#include "Emitter.h"
#include "../SGD Wrappers/SGD_GraphicsManager.h"
#include "GameplayState.h"

Particle Emitter::CreateParticle()
{
	//m_ptPosition = m_pOwner->GetPosition();

	//m_pFlyweight->AddRef();
	Particle temp(m_pFlyweight);
	temp.GetOwner()->AddRef();

	temp.SetColor(m_pFlyweight->GetColor());
	temp.SetLifeSpan((m_pFlyweight->GetMaxLife() == m_pFlyweight->GetMinLife() ? m_pFlyweight->GetMaxLife() : ((rand() % (int)((m_pFlyweight->GetMaxLife() - m_pFlyweight->GetMinLife()) * 1000) + (m_pFlyweight->GetMinLife() * 1000)) / 1000)));
	switch (GetShape())
	{
	case 0:
	{
		temp.SetPosition(GetPosition());
		break;
	}
	case 1:
	{
		int x = (int)((rand() % GetWidth()) + GetPosition().x);
		int y = (int)(GetPosition().y);
		SGD::Point tempPoint((float)x, (float)y);
		temp.SetPosition(tempPoint);
		break;
	}
	case 2:
	{
		int x = (int)((rand() % GetWidth()) + GetPosition().x);
		int y = (int)((rand() % GetHeight()) + GetPosition().y);
		SGD::Point tempPoint((float)x, (float)y);
		temp.SetPosition(tempPoint);
		break;
	}
	case 3:
	{
		float radius = (float)(rand() % GetRadius());
		float randomAngle = (float)(rand() % 360);
		int x = (int)((GetPosition().x + (radius / 2)) + ((radius) * (float)std::cos(randomAngle)));
		int y = (int)((GetPosition().y + (radius / 2)) + ((radius) * (float)std::sin(randomAngle)));
		SGD::Point tempPoint((float)x, (float)y);
		temp.SetPosition(tempPoint);
		break;
	}

	}
	temp.SetRoation(m_pFlyweight->GetRotation());
	temp.SetScale(m_pFlyweight->GetScale());
	temp.SetVelocity(temp.InitializeVelocity());

	return temp;
}

void Emitter::ResetParticle(Particle& p)
{
	p.SetOwner(*m_pFlyweight);
	p.Reset();
}

Emitter::Emitter(Flyweight fw, float Max)
{
	m_pFlyweight = new Flyweight(fw);

	m_nMaxParticles = (int)Max;
	m_fSpawnTimer = 0.0f;
}

Emitter::~Emitter()
{
}

void Emitter::Update(float dt)
{
	m_ptPosition = SGD::Point(m_pOwner->GetPosition().x + m_nOffsetX, m_pOwner->GetPosition().y + m_nOffsetY);
	if (GetLooping())
	{
		if (m_AliveVec.size() != 0)
		{
			for (unsigned int i = 0; i < m_AliveVec.size(); i++)
			{
				m_AliveVec[i].Update(dt);
				if (m_AliveVec[i].GetLifeLeft() <= 0.0f)
				{
					Particle temp = CreateParticle();
					//temp.GetOwner()->AddRef();

					m_AliveVec.erase(m_AliveVec.begin() + i);
					m_pFlyweight->Release();

					if (m_AliveVec.size() == 0)
						break;
					i--;

				}
			}
		}
		m_fSpawnTimer += dt;
		
			if (m_fSpawnTimer >= m_fSpawnRate && m_AliveVec.size() < (unsigned int)GetMaxParticles())
		{
			Particle temp = CreateParticle();

			//temp.GetOwner()->AddRef();
			m_AliveVec.push_back(temp);
			m_fSpawnTimer = 0.0f;

		}
	}
	else 
	{

		if (!m_bHasLooped)
		{
			for (int i = 0; i < GetMaxParticles(); i++)
			{
				Particle temp = CreateParticle();

				//temp.GetOwner()->AddRef();
				m_AliveVec.push_back(temp);
			}
		}

		m_bHasLooped = true;


		if (m_AliveVec.size() != 0)
		{
			for (unsigned int i = 0; i < m_AliveVec.size(); i++)
			{
				m_AliveVec[i].Update(dt);
				if (m_AliveVec[i].GetLifeLeft() <= 0.0f)
				{
					Particle temp = CreateParticle();
					//temp.GetOwner()->AddRef();

					m_AliveVec.erase(m_AliveVec.begin() + i);
					m_pFlyweight->Release();
					if (m_AliveVec.size() == 0)
						break;
					i--;

				}
			}
		}

	}
}

void Emitter::Render()
{
	for (unsigned int i = 0; i < m_AliveVec.size(); i++)
	{
		m_AliveVec[i].Render();
	}
}

void Emitter::SetImageID(const char * str)
{
	m_szImageID = str;
}

void Emitter::SetFlyweight(Flyweight fw)	
{
	m_pFlyweight = new Flyweight(fw);
	
}

void Emitter::DeleteFlyweight()
{
	m_pFlyweight->Release();
}